package com.yuanxiao.common.core.utils;

import cn.hutool.core.codec.Base64;

import java.nio.charset.StandardCharsets;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.Signature;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.*;


/**
 * Map工具类
 */
public class MapUtils extends HashMap<String, Object> {

    @Override
    public MapUtils put(String key, Object value) {
        super.put(key, value);
        return this;
    }
    /**
     * sign签名算法: rasa加密-》签名-》base64编码
     *  map 按 key ASCII码升序排序
     * @return base64Str
     */
    public static String sign(Map<String, Object> map,String publicKey,String privateKey) {
        Map<String, Object> result = new HashMap<>();
        map.entrySet().stream()
                .sorted(Map.Entry.comparingByKey())
                .forEachOrdered(x -> result.put(x.getKey(), x.getValue()));
        StringBuilder str = new StringBuilder();
        result.forEach((key, value) -> {
            str.append(key);
            str.append("=");
            str.append(value);
            str.append("&");
        });
        str.deleteCharAt(str.length() - 1);

        String[] sortedKeys = map.keySet().toArray(new String[]{});
        Arrays.sort(sortedKeys);// 排序请求参数
        StringBuilder s2 = new StringBuilder();
        for (String key : sortedKeys) {
            s2.append(key).append("=").append(map.get(key)).append("&");
        }
        s2.deleteCharAt(s2.length() - 1);
//        System.out.println(str);
//        System.out.println(s2);
//        //rsa加密输出base64Str
//        RSA rsa = new RSA(privateKey,publicKey);
//        byte[] encrypt = rsa.encrypt(s2.toString(), KeyType.PrivateKey);
//        // 签名
//        Sign sign = SecureUtil.sign(SignAlgorithm.SHA1withRSA);
//        byte[] signed = sign.sign(encrypt);
//        return Base64.encode(signed);
        return sign(s2.toString(),privateKey);
    }

    /**
     * 返回内容签名
     *
     * @param content    待签名的内容
     * @param privateKey Base64 编码的私钥
     * @return 签名
     */
    public static String sign(String content, String privateKey) {
        try {
            PKCS8EncodedKeySpec pkcs8 = new PKCS8EncodedKeySpec(Base64.decode(privateKey.getBytes(StandardCharsets.UTF_8)));
            KeyFactory kf = KeyFactory.getInstance("RSA");
            PrivateKey pk = kf.generatePrivate(pkcs8);

            Signature sha1WithRSA = Signature.getInstance("SHA1WithRSA");
            sha1WithRSA.initSign(pk);
            sha1WithRSA.update(content.getBytes(StandardCharsets.UTF_8));

            return Base64.encode(sha1WithRSA.sign());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public static void main(String[] args) {
        String privateKey = "MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAKezLTpx3aipo2kwtD0Aw2abbsWVCcbKPEOKCmC4fdUlJZmBDJ75S6fN4cnjQtymqpwyqJQb4Mm0vuKQIHv42NfkRdNiV0qBu3B+zKicaVmy4ZHoBnD2ffhP6CaIE4vutJ9fPy4CBWNBtbbg0nM67QGm/eTK+PfaOh2TFUHfjqoxAgMBAAECgYBXW1vVFRmNUYjhM9C/8lTXb2JdpExqdFC+MftD9Pb/gBE9DF9htKU3bWUPwMXEoUFAipcMSBVpnTDOXpu9WJzDyWBEj/4lyCDD1WU+Yt95+aeOcD8ld0WKthtoX01m+sGWUU0DeghMLzRQTMzYEhMVhZkqiKH/y1oUXc4IHlwTjQJBANr2ZtvXuTmpJuw3KquMI7G7wbi6tdHVWdyF9PzS+dyOZy2Rxom1Ti7BrXUOJoT2PxnAP6U+PP7p1n5Dnio3U88CQQDEEPt1Cxsk4hfayfRzSJJfh9I9qqMueXeG/e58GVPWaPNL3EuqC9eO2A4fMDzZ/ogdxi5zeuHevdBoKiIDs6H/AkA+ERRtAsRFXPZkhOq6f9nqWo96HqrFVRXI1cvxEpiy9Ua3+xdtF5CW3l2dzaoLjIWsdftUisTdeUlMtzwROWevAkEAkNoDDMuxuCQZf5iosuswyMctekWw3Ur8FY1RPfnwSH2tEaSlefHZxTy14jDfJCa6JVUfSE3GxaryZ6KJErcJvQJBAJyPGgf4n5FkqlV+EwBQkUCWGq2qskXc0pzKWDZTB9PReLPSt4t2ENcBguKs+qi/jwXIF0Jj/9Bn0MfZZTYuu/M=";
        String publicKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCnsy06cd2oqaNpMLQ9AMNmm27FlQnGyjxDigpguH3VJSWZgQye+UunzeHJ40LcpqqcMqiUG+DJtL7ikCB7+NjX5EXTYldKgbtwfsyonGlZsuGR6AZw9n34T+gmiBOL7rSfXz8uAgVjQbW24NJzOu0Bpv3kyvj32jodkxVB346qMQIDAQAB";
        Map<String, Object> map = new HashMap<>();
        map.put("app_id","552018071901178");
        map.put("sub_app_id","552018071901179");
        map.put("method","trade.percreate");
        map.put("timestamp","2018-09-26 11:10:13");
        map.put("sign_type","RSA");
        map.put("nonce","1537931413888");
        map.put("biz_content","{\"pay_way\":\"WECHAT\",\"create_ip\":\"192.168.13.103\",\"create_time\":\"20180926111013\",\"expire_time\":\"20180926111513\",\"total_amount\":0.01,\"out_order_no\":\"1537931413888\",\"body\":\"订单描述\",\"terminal_id\":\"terminalId\",\"operator_id\":\"operatorId\",\"notify_url\":\"http://172.28.250.135:9098\"}");
        System.out.println(MapUtils.sign(map,publicKey,privateKey));
//        RSA rsa = new RSA(privateKey,publicKey);
//        System.out.println("私钥");
//        System.out.println(rsa.getPrivateKeyBase64());
//        System.out.println("公钥");
//        System.out.println(rsa.getPublicKeyBase64());
        //公钥加密，私钥解密
//        byte[] encrypt = rsa.encrypt(StrUtil.bytes("我是一段测试aaaa", CharsetUtil.CHARSET_UTF_8), KeyType.PublicKey);
//        byte[] decrypt = rsa.decrypt(encrypt, KeyType.PrivateKey);
//
////Junit单元测试
////Assert.assertEquals("我是一段测试aaaa", StrUtil.str(decrypt, CharsetUtil.CHARSET_UTF_8));
//
////私钥加密，公钥解密
//        byte[] encrypt2 = rsa.encrypt(StrUtil.bytes("我是一段测试aaaa", CharsetUtil.CHARSET_UTF_8), KeyType.PrivateKey);
//        byte[] decrypt2 = rsa.decrypt(encrypt2, KeyType.PublicKey);
//
//
//        byte[] data = "我是一段测试字符串".getBytes();
//        Sign sign = SecureUtil.sign(SignAlgorithm.SHA1withRSA);
////签名
//        byte[] signed = sign.sign(data);
//
//        String a = "伦家是一个非常长的字符串";
////5Lym5a625piv5LiA5Liq6Z2e5bi46ZW/55qE5a2X56ym5Liy
//        String encode = Base64.encode(a);
//
//// 还原为a
//        String decodeStr = Base64.decodeStr(encode);

    }

}
